package com.sixth.config;

import com.sixth.shiro.ShiroRealm;
import com.sixth.shiro.AdminShiroSessionManager;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import java.util.LinkedHashMap;

/**
 * @ClassName SpringShiroConfig
 * @Description TODO
 * @Author XiaoWJ
 * @Date 2022/9/9 9:52
 **/

@Configuration
public class SpringShiroConfig {


    @Bean
    public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm,
                                                     AdminShiroSessionManager adminShiroSessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置认证器，如果没有设置，则采用默认的认证器 → ModularRealmAuthenticator
        // 多账号管理体系 → 设置自定义的认证器
        //securityManager.setAuthenticator();
        // 设置授权器，如果没有设置，则采用默认的授权器 → ModularRealmAuthorizer
        //securityManager.setAuthorizer();
        // 给SecurityManager设置Realm信息 → 给默认的认证器和授权器设置Realm信息
        securityManager.setRealm(shiroRealm);
        //如果是多个realm，则使用setRealms方法
        //securityManager.setRealms();

        securityManager.setSessionManager(adminShiroSessionManager);
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 配置ShiroFilter执行链

        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        filterChainDefinitionMap.put("admin/auth/login", "anon");
        filterChainDefinitionMap.put("admin/auth/info", "anon");
        filterChainDefinitionMap.put("admin/**", "authc");

        // 设置权限认证未通过的重定向地址为"admin/auth/noAuthc"
        shiroFilterFactoryBean.setLoginUrl("admin/auth/noAuthc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }

    // 配置url与权限相对应切面的通知器

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    // 配置密码比较器

    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();

        // 加密算法的名称
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");

        // 配置加密的次数为2次
        hashedCredentialsMatcher.setHashIterations(2);

        // 配置为存储为16进制
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);

        return hashedCredentialsMatcher;
    }

    // 配置shiroRealm

    @Bean
    public ShiroRealm shiroRealm(HashedCredentialsMatcher hashedCredentialsMatcher) {
        ShiroRealm shiroRealm = new ShiroRealm();

        shiroRealm.setCachingEnabled(true);
        //启用身份验证缓存，即缓存AuthenticationInfo信息，默认false
        shiroRealm.setAuthenticationCachingEnabled(true);
        //缓存AuthenticationInfo信息的缓存名称 在ehcache-shiro.xml中有对应缓存的配置
        shiroRealm.setAuthenticationCacheName("authenticationCache");
        //启用授权缓存，即缓存AuthorizationInfo信息，默认false
        shiroRealm.setAuthorizationCachingEnabled(true);
        //缓存AuthorizationInfo信息的缓存名称  在ehcache-shiro.xml中有对应缓存的配置
        shiroRealm.setAuthorizationCacheName("authorizationCache");


        // 配置自定义密码比较器
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher);

        return shiroRealm;
    }

}
